[org 0x7c00]		; adjust offsets assuming this is loaded to 0x7c00 in RAM
KERNEL_OFFSET equ 0x1000
jmp	start

; data block
MSG_BOOT:
db	'Booting Jeff_OS...',0h0A,0h0D,0

MSG_BOOT_PM:
db	'Entered 32 bit protected mode!'
times 60 db ' '
db 0

MSG_BOOT_KERNEL:
db	'Loading kernel into memory...',0

HEX_OUT:
db	'0x1234',0h0A,0h0D,0

BOOT_DRIVE:
db	0x00


; program block

start:

mov	[BOOT_DRIVE],	dl

mov	bp,	0x7c00		; set stack's base pointer
mov	sp,	bp

mov	bx,	MSG_BOOT
call	print_string

call	load_kernel

call	switch_to_pm

jmp	$ 		; won't get here

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; functions

; takes a string's address in bx and prints it
%include "print_string.asm"

; read dh sectors from device dl and put them in es:bx
%include "disk_read.asm"

; global descriptor table setup
%include "gdt.asm"

; prints to the top left of video memory in protected mode
%include "print_string_pm.asm"

; switch from 16 bit real to 32 bit protected
%include "switch_to_pm.asm"

; print hex function
; prints the value stored in dx as hex (ex: 0x1f32)
;print_hex:
;pusha
;
;; we're gonna use the 4 8 bit c/d registers to hold each character
;mov	cx,	dx
;and	ch,	0xf0	; 0b11110000   -   gives high half-byte
;and	dh,	0x0f	; 0b00001111   -   gives low half-byte
;and	cl,	0xf0	; 0b11110000
;and	dl,	0x0f	; 0b00001111
;
;shr	ch,	4	; shift right by four to get 0-F
;shr	cl,	4	; ^
;
;; convert the raw bytes into ascii for printing
;printhex_cmp1:
;add	ch,	0d48
;cmp	ch,	0x39
;jle	printhex_cmp2
;add	ch,	0d07
;printhex_cmp2:
;add	dh,	0d48
;cmp	dh,	0x39
;jle	printhex_cmp3
;add	dh,	0d07
;printhex_cmp3:
;add	cl,	0d48
;cmp	cl,	0x39
;jle	printhex_cmp4
;add	cl,	0d07
;printhex_cmp4:
;add	dl,	0d48
;cmp	dl,	0x39
;jle	printhex_cmpend
;add	dl,	0d07
;printhex_cmpend:
;
;; copy the four bytes into the correct positions in hex_out
;mov	[hex_out+2],	ch
;mov	[hex_out+3],	dh
;mov	[hex_out+4],	cl
;mov	[hex_out+5],	dl
;
;mov	bx,	hex_out
;call	print_string
;
;popa
;ret
;


[bits 16]

load_kernel:
mov	bx,	MSG_BOOT_KERNEL
call	print_string

mov	bx,	KERNEL_OFFSET
mov	dh,	15
mov	dl,	[BOOT_DRIVE]
call	disk_read
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; this is where we appear after switching to 32 bit mode

[bits 32]
BEGIN_PM:

mov	ebx,	MSG_BOOT_PM
call	print_string_pm

call	KERNEL_OFFSET

jmp	$			; hang forever


times 510-($-$$) db 0	; zero padding

dw	0xaa55		; magic boot sector bytes
